package com.cskaoyan.util;

import com.cskaoyan.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ProxyUtil {

    public static <T> T getServiceProxy(Class<T> clazz){
        T proxy = (T) Enhancer.create(clazz, new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                //获得该类的实例
                T t = clazz.newInstance();
                SqlSession sqlSession = MyBatisUtil.getSqlSession();
                //当前的UserMapper和service层的里的userMapper并不是同一个
                //UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
                //是service里的userMapper 赋值为上面刚初始化的userMapper
                //Field userMapper = clazz.getDeclaredField("userMapper");

                //反射
                Field[] declaredFields = clazz.getDeclaredFields();

                //Field userMapper1 = clazz.getDeclaredField("userMapper");
                for (Field field : declaredFields) {
                    if (field.getName().contains("Mapper")) {
                        field.setAccessible(true);
                        // UserMapper.class
                        Class<?> type = field.getType(); //UserMapper.class
                        Object mapper = sqlSession.getMapper(type); //获得mapper代理对象
                        // 给t这个对象的field这个成员变量设置值为mapper
                        field.set(t,mapper);
                    }
                }
                //获得SqlSession并且给Service的mapper成员变量赋值
                Object invoke = method.invoke(t, objects);
                //提交事务，关闭SqlSession
                sqlSession.commit();
                sqlSession.close();
                return invoke;
            }
        });
        return proxy;
    }
    public static <T> T getServiceProxy(T t){
        T proxy = (T) Enhancer.create(t.getClass(), new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                //获得该类的实例
                SqlSession sqlSession = MyBatisUtil.getSqlSession();
                //当前的UserMapper和service层的里的userMapper并不是同一个
                //UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
                //是service里的userMapper 赋值为上面刚初始化的userMapper
                //Field userMapper = clazz.getDeclaredField("userMapper");

                //反射
                Field[] declaredFields = t.getClass().getDeclaredFields();

                //Field userMapper1 = clazz.getDeclaredField("userMapper");
                for (Field field : declaredFields) {
                    if (field.getName().contains("Mapper")) {
                        field.setAccessible(true);
                        // UserMapper.class
                        Class<?> type = field.getType(); //UserMapper.class
                        Object mapper = sqlSession.getMapper(type); //获得mapper代理对象
                        // 给t这个对象的field这个成员变量设置值为mapper
                        field.set(t,mapper);
                    }
                }
                //获得SqlSession并且给Service的mapper成员变量赋值
                Object invoke = method.invoke(t, objects);
                //提交事务，关闭SqlSession
                sqlSession.commit();
                sqlSession.close();
                return invoke;
            }
        });
        return proxy;
    }
}
